/*
 * 原版接口
 */
import * as server from "@minecraft/server";
/*
 * 蛋白石数据
 */
import * as data_format from "../data/format";
/*
 * 蛋白石组件
 */
import * as math_tools from "./math_tools";
/*
 * 导出模块
 */
export {
    CreateEmptyProperty,
    CreateProperty,
    AlterProperty,
    MergeProperty,
    GetProperty,
    SetProperty,
};
/**
 * * 随机生成一个符文类型。
 * 
 * @returns {data_format.RUNE_TYPE} 返回一个随机的符文类型枚举值。
 */
function RandomRune(): data_format.RUNE_TYPE {
    /**
     * * 符文类型数组, 每个类型都有相同的选中概率
     * 
     * @type {data_format.RUNE_TYPE[]}
     */
    const runes: data_format.RUNE_TYPE[] = [
        data_format.RUNE_ENUM.blue,
        data_format.RUNE_ENUM.green,
        data_format.RUNE_ENUM.orange,
        data_format.RUNE_ENUM.red,
        data_format.RUNE_ENUM.purple
    ];
    /**
     * * 生成一个介于0（包含）和符文类型数组的长度（不包含）之间的随机索引
     * 
     * @type {number}
     */
    const randomIndex: number = math_tools.Random({ min: 0, max: runes.length });
    /**
     * * 根据随机索引返回一个符文类型
     * 
     * @type {data_format.RUNE_TYPE}
     */
    return runes[randomIndex];
};
/**
 * * 创建 实体 的 战斗属性面板
 *
 * @param {server.Entity} entity 进行 战斗属性面板 设置 的 实体
 *
 * @param {data_format.SET_PROPERTY_PANEL} input 实体 的 战斗属性面板
 */
function CreateProperty(entity: server.Entity, input?: data_format.SET_PROPERTY_PANEL) {
    /**
     * * 定义一个辅助函数, 用于设置动态属性, 使用枚举提供的默认值
     *
     * @param {RUNE_PROPERTY_DEFAULT} key - 战斗属性面板的属性
     */
    const setProperty = (key: keyof typeof RUNE_PROPERTY_DEFAULT) => {
        entity.setDynamicProperty(`rune_hurt:${key}`, input?.[key] ?? RUNE_PROPERTY_DEFAULT[key]);
    };
    // 使用枚举设置属性, 同时允许输入覆盖默认值
    setProperty('raise_basic_attack');
    setProperty('raise_erupt_odds');
    setProperty('raise_erupt_hurt');
    setProperty('damage_increase');
    setProperty('double_damage');
    setProperty('basic_attack');
    setProperty('erupt_hurt');
    setProperty('erupt_odds');
    setProperty('add_rune');
    // 自身符文 需 特殊处理, 因为它使用了 RandomRune 函数
    entity.setDynamicProperty('rune_hurt:self_rune', input?.self_rune ?? RandomRune());
};
/**
 * * 设置 实体 的 战斗属性面板
 *
 * @param {server.Entity} object 进行 战斗属性面板 设置 的 实体
 *
 * @param {data_format.SET_PROPERTY_PANEL} input 实体 的 战斗属性面板
 */
function SetProperty(object: server.Entity, input: data_format.SET_PROPERTY_PANEL) {
    /**
     * * 获取 实体 的 原始战斗属性面板
     */
    const proto = GetProperty(object);
    /*
     * 基础伤害
     */
    object.setDynamicProperty('rune_hurt:basic_attack', input.basic_attack ?? proto.basic_attack);
    object.setDynamicProperty('rune_hurt:raise_basic_attack', input.raise_basic_attack ?? proto.raise_basic_attack);
    /*
     * 暴击概率
     */
    object.setDynamicProperty('rune_hurt:erupt_odds', input.erupt_odds ?? proto.erupt_odds);
    object.setDynamicProperty('rune_hurt:raise_erupt_odds', input.raise_erupt_odds ?? proto.raise_erupt_odds);
    /*
     * 暴击伤害
     */
    object.setDynamicProperty('rune_hurt:erupt_hurt', input.erupt_hurt ?? proto.erupt_hurt);
    object.setDynamicProperty('rune_hurt:raise_erupt_hurt', input.raise_erupt_hurt ?? proto.raise_erupt_hurt);
    /*
     * 伤害提升
     */
    object.setDynamicProperty('rune_hurt:damage_increase', input.damage_increase ?? proto.damage_increase);
    object.setDynamicProperty('rune_hurt:double_damage', input.double_damage ?? proto.double_damage);
    /*
     * 元素符文
     */
    object.setDynamicProperty('rune_hurt:add_rune', input.add_rune ?? proto.add_rune);
    object.setDynamicProperty('rune_hurt:self_rune', input.self_rune ?? proto.self_rune);
};
/**
 * * 修改 实体 的 战斗属性面板
 *
 * @param {server.Entity} object 进行 战斗属性面板 设置 的 实体
 *
 * @param {data_format.SET_PROPERTY_PANEL} input 实体 的 战斗属性面板
 */
function AlterProperty(object: server.Entity, input: data_format.SET_PROPERTY_PANEL) {
    // 如果 实体 未初始化 则 不进行 设置
    if (!object.getDynamicProperty('entity:is_initial')) return;
    /**
     * * 获取 实体 的 原始战斗属性面板
     */
    const proto = GetProperty(object);
    /*
     * 基础伤害
     */
    if (input.basic_attack) object.setDynamicProperty('rune_hurt:basic_attack', proto.basic_attack + input.basic_attack);
    if (input.raise_basic_attack) object.setDynamicProperty('rune_hurt:raise_basic_attack', proto.raise_basic_attack + input.raise_basic_attack);
    /*
     * 暴击概率
     */
    if (input.erupt_odds) object.setDynamicProperty('rune_hurt:erupt_odds', proto.erupt_odds + input.erupt_odds);
    if (input.raise_erupt_odds) object.setDynamicProperty('rune_hurt:raise_erupt_odds', proto.raise_erupt_odds + input.raise_erupt_odds);
    /*
     * 暴击伤害
     */
    if (input.erupt_hurt) object.setDynamicProperty('rune_hurt:erupt_hurt', proto.erupt_hurt + input.erupt_hurt);
    if (input.raise_erupt_hurt) object.setDynamicProperty('rune_hurt:raise_erupt_hurt', proto.raise_erupt_odds + input.raise_erupt_hurt);
    /*
     * 伤害提升
     */
    if (input.damage_increase) object.setDynamicProperty('rune_hurt:damage_increase', proto.damage_increase + input.damage_increase);
    if (input.double_damage) object.setDynamicProperty('rune_hurt:double_damage', proto.double_damage + input.double_damage);
    /*
     * 元素符文
     */
    object.setDynamicProperty('rune_hurt:add_rune', input.add_rune ?? proto.add_rune);
    object.setDynamicProperty('rune_hurt:self_rune', input.self_rune ?? proto.self_rune);
};
/**
 * * 合并 战斗属性面板
 * 
 * @param {data_format.GET_PROPERTY_PANEL} proto 原本的 战斗属性面板
 * 
 * @param {data_format.SET_PROPERTY_PANEL} alter 需要的 战斗属性面板
 * 
 * @returns {data_format.GET_PROPERTY_PANEL} 合并后的 战斗属性面板
 */
function MergeProperty(proto: data_format.GET_PROPERTY_PANEL, alter: data_format.SET_PROPERTY_PANEL): data_format.GET_PROPERTY_PANEL {
    return { ...proto, ...alter }
};
/**
 * * 获取 实体 的 战斗属性面板
 * 
 * @param {server.Entity} entity 需要获取属性面板的实体
 * 
 * @returns {data_format.GET_PROPERTY_PANEL} 实体的战斗属性面板
 */
function GetProperty(entity: server.Entity): data_format.GET_PROPERTY_PANEL {
    // 如果 实体不存在 或 不是有效实体 则 返回默认属性面板
    if (!entity || !entity.isValid()) return RUNE_PROPERTY_DEFAULT;
    /**
     * * 获取实体的属性面板值
     * 
     * @param {string} key - 属性面板的键
     * 
     * @param {any} initial - 初始值
     * 
     * @returns {any} - 属性面板的值
     */
    const getProperty = (key: string, initial: any): any => entity?.getDynamicProperty(`rune_hurt:${key}`) ?? initial;
    // 返回属性面板
    return {
        // 属性提升
        raise_basic_attack: getProperty('raise_basic_attack', RUNE_PROPERTY_DEFAULT.raise_basic_attack),
        raise_erupt_odds: getProperty('raise_erupt_odds', RUNE_PROPERTY_DEFAULT.raise_erupt_odds),
        raise_erupt_hurt: getProperty('raise_erupt_hurt', RUNE_PROPERTY_DEFAULT.raise_erupt_hurt),
        damage_increase: getProperty('damage_increase', RUNE_PROPERTY_DEFAULT.damage_increase),
        double_damage: getProperty('double_damage', RUNE_PROPERTY_DEFAULT.double_damage),
        // 基础属性
        basic_attack: getProperty('basic_attack', RUNE_PROPERTY_DEFAULT.basic_attack),
        erupt_odds: getProperty('erupt_odds', RUNE_PROPERTY_DEFAULT.erupt_odds),
        erupt_hurt: getProperty('erupt_hurt', RUNE_PROPERTY_DEFAULT.erupt_hurt),
        // 元素类型
        self_rune: getProperty('self_rune', RUNE_PROPERTY_DEFAULT.self_rune),
        add_rune: getProperty('add_rune', RUNE_PROPERTY_DEFAULT.add_rune),
    };
};
/**
 * * 创建 虚拟战斗属性面板
 * 
 * @param {data_format.SET_PROPERTY_PANEL} input  - 设定战斗属性
 * 
 * @returns {data_format.GET_PROPERTY_PANEL} - 输出战斗属性面板
 */
function CreateEmptyProperty(input: data_format.SET_PROPERTY_PANEL): data_format.GET_PROPERTY_PANEL {
    /**
     * * 基础 战斗属性面板, 使用枚举定义的默认值
     */
    const proto: data_format.SET_PROPERTY_PANEL = {};
    // 遍历枚举, 将枚举的键和值应用到 proto 对象上
    for (const key in RUNE_PROPERTY_DEFAULT) {
        if (RUNE_PROPERTY_DEFAULT.hasOwnProperty(key)) {
            proto[key] = RUNE_PROPERTY_DEFAULT[key];
        }
    };
    return MergeProperty(proto as data_format.GET_PROPERTY_PANEL, input);
};
/**
 * * 定义战斗属性面板的默认值
 */
enum RUNE_PROPERTY_DEFAULT {
    /**
     * 基础攻击提升的默认值
     */
    raise_basic_attack = 0,
    /**
     * 爆发概率提升的默认值
     */
    raise_erupt_odds = 0,
    /**
     * 爆发伤害提升的默认值
     */
    raise_erupt_hurt = 0,
    /**
     * 伤害增加的默认值
     */
    damage_increase = 0,
    /**
     * 双倍伤害的默认值
     */
    double_damage = 1,
    /**
     * 基础攻击的默认值
     */
    basic_attack = 5,
    /**
     * 爆发概率的默认值
     */
    erupt_odds = 10,
    /**
     * 爆发伤害的默认值
     */
    erupt_hurt = 150,
    /**
     * 自身符文类型的默认值
     */
    self_rune = data_format.RUNE_ENUM.void,
    /**
     * 添加符文类型的默认值
     */
    add_rune = data_format.RUNE_ENUM.void
};